package com.Netty.heart.comment;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * Created by thinkjoy on 2017/6/29.
 */
public abstract class CustomHeartbeatHandler extends SimpleChannelInboundHandler<ByteBuf> {

    public static final byte PING_MSG = 1;
    public static final byte PONG_MSG = 2;
    public static final byte CUSTOM_MSG = 3;
    protected  String name;
    private int heartbeatCount = 0;

    public CustomHeartbeatHandler(String name) {
        this.name = name;
    }

    /**
     *
     * @param channelHandlerContext
     * @param byteBuf
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        if(byteBuf.getByte(4)==PING_MSG){
            sendPongMsg(channelHandlerContext);
        }else if(byteBuf.getByte(4)==PONG_MSG){
            System.out.println(name + " get pong msg from " + channelHandlerContext.channel().remoteAddress());
        }else {
            handleData(channelHandlerContext,byteBuf);
        }
    }

    /**
     * 传ping消息
     * @param context
     */
    protected void sendPingMsg(ChannelHandlerContext context){
        ByteBuf buf=context.alloc().buffer(5);
        buf.writeInt(5);
        buf.writeByte(PING_MSG);
        buf.retain();
        context.writeAndFlush(buf);
        heartbeatCount++;
        System.out.println(name+" 传送ping消息给"+context.channel().remoteAddress()+"  count:"+heartbeatCount);
    }

    /**
     * 传pong消息
     * @param context
     */
    protected void sendPongMsg(ChannelHandlerContext context){
        ByteBuf buf=context.alloc().buffer(5);
        buf.writeInt(5);
        buf.writeByte(PONG_MSG);
        context.channel().writeAndFlush(buf);
        heartbeatCount++;
        System.out.println(name+" 传送pong消息给"+context.channel().remoteAddress()+"  count:"+heartbeatCount);
    }

    protected  abstract void handleData(ChannelHandlerContext channelHandlerContext,ByteBuf byteBuf);

    /**
     * 超时触发
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event= (IdleStateEvent) evt;
            switch (event.state()){
                case READER_IDLE:
                    handleReaderIdle(ctx);
                    break;
                case WRITER_IDLE:
                    handleWriterIdle(ctx);
                    break;
                case ALL_IDLE:
                    handleAllIdle(ctx);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("---" + ctx.channel().remoteAddress() + "正在活跃---");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("---" + ctx.channel().remoteAddress() + " 已经掉线---");
    }

    protected  void handleAllIdle(ChannelHandlerContext ctx){
        System.out.println("读写超时");
    }

    protected  void handleWriterIdle(ChannelHandlerContext ctx){
        System.out.println("写超时");
    }

    protected  void handleReaderIdle(ChannelHandlerContext ctx){
        System.out.println("读超时");
    }
}
